import sys
import io
import time
import json
import requests
import pyautogui
from PyQt5.QtWidgets import (QApplication, QMainWindow, QPushButton,
                             QLabel, QVBoxLayout, QWidget, QMessageBox,
                             QLineEdit, QHBoxLayout)
from PyQt5.QtCore import Qt, QThread, pyqtSignal, QSettings
from PyQt5.QtGui import QKeySequence

from config import Config


class RecognitionThread(QThread):
    finished = pyqtSignal(str)
    error = pyqtSignal(str)

    def run(self):
        try:
            print("开始截图识别...")
            image = pyautogui.screenshot()
            buffer = io.BytesIO()
            image.save(buffer, format='PNG')
            buffer.seek(0)

            print("发送请求到服务端...")
            response = requests.post(
                Config.API_ENDPOINT,
                files={'image': ('screenshot.png', buffer, 'image/png')}
            )
            response.raise_for_status()
            # 修正这里，确保是字符串
            result = response.json().get('text', '')

            # 先释放所有可能被按住的键
            pyautogui.keyUp('shift')
            pyautogui.keyUp('ctrl')
            pyautogui.keyUp('alt')

            time.sleep(0.05)

            # 逐字符输入，字母按Shift
            for char in result:
                if char.isalpha():
                    pyautogui.keyDown('shift')
                    pyautogui.press(char.lower())
                    pyautogui.keyUp('shift')
                else:
                    pyautogui.press(char)

            pyautogui.press('enter')
            time.sleep(0.02)
            pyautogui.press('enter')

            self.finished.emit("识别完成并已输入文本")

        except Exception as e:
            self.error.emit(f"识别失败: {str(e)}")


class HotkeyLineEdit(QLineEdit):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setPlaceholderText("按下组合键设置热键")
        self.setReadOnly(False)
        self.current_keys = set()
        self.setCursorPosition(0)
        self.setFocusPolicy(Qt.StrongFocus)

    def focusInEvent(self, event):
        super().focusInEvent(event)
        self.setCursorPosition(0)

    def focusOutEvent(self, event):
        super().focusOutEvent(event)
        self.setCursorPosition(0)

    def keyPressEvent(self, event):
        key = event.key()
        modifiers = event.modifiers()

        if key in (Qt.Key_Shift, Qt.Key_Control, Qt.Key_Alt, Qt.Key_Meta):
            return

        mod_text = ""
        if modifiers & Qt.ControlModifier:
            mod_text += "Ctrl+"
        if modifiers & Qt.ShiftModifier:
            mod_text += "Shift+"
        if modifiers & Qt.AltModifier:
            mod_text += "Alt+"
        if modifiers & Qt.MetaModifier:
            mod_text += "Win+"

        key_text = QKeySequence(key).toString()
        hotkey = mod_text + key_text
        self.setText(hotkey)

        self.current_keys = set()
        if modifiers & Qt.ControlModifier:
            self.current_keys.add("ctrl")
        if modifiers & Qt.ShiftModifier:
            self.current_keys.add("shift")
        if modifiers & Qt.AltModifier:
            self.current_keys.add("alt")
        self.current_keys.add(key_text.lower())


class ScreenshotApp(QMainWindow):
    def __init__(self):
        super().__init__()
        self.current_hotkey = "ctrl+m"  # 默认热键
        self.hotkey_handle = None       # 保存自己的热键ID
        self.recognition_thread = None
        self.settings = QSettings("MyCompany", "ScreenshotTool")
        self.initUI()
        self.load_settings()
        self.setup_hotkey()

    def initUI(self):
        self.setWindowTitle("截图识别工具")
        self.setGeometry(300, 300, 350, 200)

        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        layout = QVBoxLayout()

        hotkey_layout = QHBoxLayout()
        self.hotkey_label = QLabel("当前热键:", self)
        hotkey_layout.addWidget(self.hotkey_label)

        self.hotkey_edit = HotkeyLineEdit(self)
        self.hotkey_edit.setStyleSheet("""
                QLineEdit {
                    selection-background-color: #3498db;
                    selection-color: black;
                }
            """)
        hotkey_layout.addWidget(self.hotkey_edit)

        self.btn_set_hotkey = QPushButton("设置热键", self)
        self.btn_set_hotkey.clicked.connect(self.set_hotkey)
        hotkey_layout.addWidget(self.btn_set_hotkey)

        layout.addLayout(hotkey_layout)

        self.label = QLabel("按热键截图并识别", self)
        self.label.setAlignment(Qt.AlignCenter)
        layout.addWidget(self.label)

        central_widget.setLayout(layout)

        try:
            import keyboard
            if not keyboard.is_pressed('ctrl'):
                QMessageBox.warning(self, "权限警告", "请以管理员身份运行程序，否则热键可能无效")
        except Exception as e:
            QMessageBox.warning(self, "错误", f"键盘模块初始化失败: {e}")

    def load_settings(self):
        saved_hotkey = self.settings.value("hotkey", "ctrl+m")
        if saved_hotkey:
            self.current_hotkey = saved_hotkey
            self.hotkey_label.setText(f"当前热键: {saved_hotkey}")

    def save_settings(self):
        self.settings.setValue("hotkey", self.current_hotkey)

    def setup_hotkey(self):
        try:
            import keyboard

            # 如果有上一次的热键，解绑
            if self.hotkey_handle:
                keyboard.unhook(self.hotkey_handle)
                self.hotkey_handle = None

            keys = self.current_hotkey.lower().split('+')
            hotkey_str = '+'.join(keys)

            self.hotkey_handle = keyboard.add_hotkey(
                hotkey_str,
                self.start_recognition
            )

            self.hotkey_label.setText(f"当前热键: {self.current_hotkey}")

        except ImportError:
            self.label.setText("键盘模块不可用，无法设置热键")

    def set_hotkey(self):
        new_hotkey = self.hotkey_edit.text().lower()
        if not new_hotkey:
            QMessageBox.warning(self, "警告", "请先按下组合键设置热键")
            return

        self.current_hotkey = new_hotkey
        self.setup_hotkey()
        self.save_settings()
        QMessageBox.information(self, "成功", f"热键已设置为: {new_hotkey}")

    def start_recognition(self):
        if self.recognition_thread and self.recognition_thread.isRunning():
            return

        self.recognition_thread = RecognitionThread()
        self.recognition_thread.finished.connect(self.on_recognition_success)
        self.recognition_thread.error.connect(self.on_recognition_error)
        self.recognition_thread.start()
        self.label.setText("正在识别...")

    def on_recognition_success(self, message):
        self.label.setText(message)

    def on_recognition_error(self, error_msg):
        self.label.setText("识别失败")
        QMessageBox.critical(self, "错误", error_msg)

    def closeEvent(self, event):
        if self.recognition_thread and self.recognition_thread.isRunning():
            self.recognition_thread.quit()
            self.recognition_thread.wait()

        # 退出时解绑自己的热键
        try:
            import keyboard
            if self.hotkey_handle:
                keyboard.unhook(self.hotkey_handle)
        except Exception:
            pass

        self.save_settings()
        event.accept()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = ScreenshotApp()
    ex.show()
    sys.exit(app.exec_())
